#ifndef MOVABLES_H
#define MOVABLES_H

#include <vector>
#include <Allegro5\allegro.h>
#include "GlobalVariables.h"
#include "Point.h"
#include "Map.h"
#include "Utilities.h"

using namespace std;

enum DetectionResult{CAN_MOVE, COLLISION, MONSTER_DEAD, DIGDUG_DEAD};

// Class Movables
/*!  \brief Movables is the parent class for all movable types.

	 This is not a pure interface class, but makes use of polymorphism in several of its functions.
	 Its main role is to provide an interface for the movement of the movable game objects 
	 and collision detection while these objects are moving
*/

class Movables
{
public: 

	//!  Class constructor
	Movables(Point location, int radius, int speed, Movable_type type, ALLEGRO_BITMAP* bitmap);	
	Movables(){}

	/*!  \brief This performs movement of for given movable object. 
	
		In the function , a call is made to 
		other functions which perform collision checking. If a move is allowed, the object's position is updated to the new location.
		
		The Map object containing the location of all elements on the game grid including sand, holes, monsters, 
		digdug and projectiles is passed into the function and is used for collision detection. 
		It is passed by reference to avoid the inefficient copying of a large object.
	*/
	virtual DetectionResult move(Map &map) = 0;	
	
	/*! \brief Each derived class has certain conditions which must be fulfilled in order to allow the character to move; 
		when these criteria are met a call is made to this function.
	
		For Digdug a user keyboard direction must be entered. For Digdug's projectile, the shoot button must be pressed.
		For Monsters, the monster cannot be in the stage between being hit by a projectile and blowing up. 

		This function also allows the direction of the movable to be changed to the input direction. 
	
	*/
	virtual void allowMove(Direction direction) = 0;

	/*! \brief This checks the map elements in the location the movable is attempting to enter for possible collisions.

		The function is defined in the Movables parent class to uphold the Dry principle, as its implementation remains constant for all movable types.
		Its main action is to call the pure virtual collisionCheck funtion, to determine the result of an attempted move into each
		element of the map that the moved object is trying to occupy.

	*/
	DetectionResult checkMoveInDirection(Point location_from, Direction direction, Map& map);
	
	// Set functions for given parameters:

	void direction(Direction dir);	
	void location(Point location);
	
	// Get functions for given parameters:

	Direction direction();
	Point location();
	int radius();
	Movable_type type();
	ALLEGRO_BITMAP *bitmap(); 

protected:

	Point _location;	
	int _radius;
	Direction _direction;	// Enumm type defined in GloabalVariables 
	int _speed;
	ALLEGRO_BITMAP * _bitmap;
	Movable_type _type;		// Enumm type defined in GloabalVariables

private:

	/*! \brief This is used to perform collision checking for a specific movable type 
	and an object type occupying a given position on the map.

	Naturally, as the collision rules for each derived class differ from each other, 
	the implementation of the function is left to each derived class.
	*/
	virtual DetectionResult collisionCheck(Movable_type position_type) const = 0;
	
};

#endif